package paint;

/**
 * La classe Point sert à la création d'un point
 * @author Romain Bustos
 * @author Matthieu Perrin
 * @version 1.0
 */
public class Point extends Forme{
    
    private int X;      
    private int Y;       
    private Point o;       
    
    /**
    *<b>Constructeur par defaut de la classe Point</b><br> 
    * <p>
    * Est utilisé lors d'une construction sans arguements d'un point <br>
    * X = 1 <br>
    * Y = 1 <br>
    * l'origine est un nouveau point à 0,0
    * </p>
    */
    public Point(){
	X = 1;
	Y = 1;
	o = new Point(0,0);
    }

    /**
    *<b>Constructeur de surcharge de la classe Point</b><br> 
    * <p>
    * Est utilisé lors de la construction d'un point <br>
    * </p>
    * @param X1
    *       abscisse du nouveau point
    * @param Y1
    *       ordonnée du nouveau point
    */
    public Point(int X1, int Y1){
	this.X = X1;
	this.Y = Y1;
    }
    
    /**
    *<b>Constructeur de surcharge de la classe Point</b><br> 
    * <p>
    * Est utilisé lors de le construction d'un point<br>
    * </p>
    * @param X2
    *       abscisse du noouveau point
    * @param Y2
    *       ordonnée du nouveau point
    * @param o2 
    *       origine du nouveau point
    */
    public Point(int X2, int Y2, Point o2){
        this.X = X2;
        this.Y = Y2;
        this.o = o2;
    }

    /**
    *<b>Constructeur secondaire de la classe Point</b><br> 
    * <p>
    * Est utilisé pour créer le clone du point courant<br>
    * </p>
    * @return Point
    */
    @Override
    public Point createClone(){
        return new Point(this.X, this.Y, this.o);
    }
    
    
    /**
    *<b>Constructeur secondaire de la classe Point</b><br> 
    * <p>
    * Est utilisé pour créer un point symetrique par rapport à l'origine du point courant<br>
    * </p>
    * @return Point
    */
    public Point createSymetrieO(){
        return new Point(-this.X, -this.Y, this.o);
    }
    
    /**
    *<b>Constructeur secondaire de la classe Point</b><br> 
    * <p>
    * Est utilisé pour créer un point symetrique par rapport à l'abscisse du point courant<br>
    * </p>
    * @return Point
    */
    public Point createSymetrieX(){
        return new Point(this.X, -this.Y, this.o);
    }
    
    
    /**
    *<b>Constructeur secondaire de la classe Point</b><br> 
    * <p>
    * Est utilisé pour créer un point symetrique par rapport à l'ordonnée du point courant<br>
    * </p>
    * @return Point
    */
    public Point createSymetrieY(){
        return new Point(-this.X, this.Y, this.o);
    }

    
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour recupérer l'abscisse du point courant<br>
    * </p>
    * @return abscisse du point courant
    */
    public int getX(){
        return this.X;
    }
    
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour recupérer l'ordonnée du point courant<br>
    * </p>
    * @return ordonnée du point courant
    */
    public int getY(){
        return this.Y;
    }
    
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour recupérer l'origine du point courant<br>
    * </p>
    * @return origine du point courant
    */
    public Point getO() {
        return o;
    }
    
    /**
    *<b>Mutateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour modifier la valeur d'abscisse du point courant<br>
    * </p>
    * @param X
    *       nouvelle valeur d'abscisse
    */
    public void setX(int X){
        this.X = X;
    }
    
    
    /**
    *<b>Mutateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour modifier la valeur d'ordonné du point courant<br>
    * </p>
    * @param Y
    *       nouvelle valeur d'ordonné
    */
    public void setY(int Y){
        this.Y = Y;
    }
    
    
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour savoir si un point est un symétrique par rapport à X d'un autre point<br>
    * </p>
    * @param P1
    *       Point de comparaison
    * @return Vrai / Faux
    */
    public boolean isSymetrieX(Point P1){
        return ((this.getX() == P1.getX()) && (this.getY() == -P1.getY()) && (this.getO() == P1.getO()));
    }
    
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour savoir si un point est un symétrique par rapport à Y d'un autre point<br>
    * </p>
    * @param P1
    *       Point de comparaison
    * @return Vrai / Faux
    */
    public boolean isSymetrieY(Point P1){
        return ((this.getX() == -P1.getX()) && (this.getY() == P1.getY()) && (this.getO() == P1.getO()));
    }
    
    
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour savoir si un point est un symétrique par rapport à l'origine d'un autre point<br>
    * </p>
    * @param P1
    *       Point de comparaison
    * @return Vrai / Faux
    */
    public boolean isSymetrieO(Point P1){
        return ((this.getX() == -P1.getX()) && (this.getY() == -P1.getY()) && (this.getO() == P1.getO()));
    }
    
    
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour donner un aperçu d'un point sous forme de texte<br>
    * </p>
    * @return détail d'un point
    */
    @Override
    public String toString(){
        return "X: " + this.X + " Y: " + this.Y;
    }
    
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour connaitre la distance entre deux points<br>
    * </p>
    * @param P1
    *       Point de comparaison
    * @return double => distance entre deux points
    */
    public double distance(Point P1){
        double dist;
        double dx = this.X - P1.X;
        double dy = this.Y - P1.Y;
        dist = (dx*dx) + (dy*dy);
        
        return java.lang.Math.sqrt(dist);
    }
   
    /**
    *<b>Observateur de la classe Point</b><br> 
    * <p>
    * Est utilisé pour savoir si deux points sont égaux<br>
    * </p>
    * @param P1
    *       Point de comparaison
    * @return boolean => Vrai / Faux
    */
    public boolean equals(Point P1){
        return (this.X == P1.getX() && this.Y == P1.getY() && this.o == P1.getO());
    }
}
